﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel;

namespace Dimas.Framework.Common.Utils
{
    public static class DynamicServiceClient<TServiceContract>
    {
        private static ChannelFactory<TServiceContract> _ChannelFactory;
        private static ChannelFactory<TServiceContract> ChannelFactory
        {
            get
            {
                if (_ChannelFactory == null || _ChannelFactory.State != CommunicationState.Opened)
                    _ChannelFactory = GetChannelByContract(typeof(TServiceContract).FullName);

                return _ChannelFactory;
            }
        }

        public static void Invoke(Action<TServiceContract> call)
        {
            var proxy = (IClientChannel)ChannelFactory.CreateChannel();
            bool success = false;
            try
            {
                call.Invoke((TServiceContract)proxy);

                proxy.Close();
                success = true;
            }
            finally
            {
                if (!success)
                    proxy.Abort();
            }
        }

        public static TResult Invoke<TResult>(Func<TServiceContract, TResult> call)
        {
            var proxy = (IClientChannel)ChannelFactory.CreateChannel();
            bool success = false;
            try
            {
                TResult result = call.Invoke((TServiceContract)proxy);

                proxy.Close();
                success = true;

                return result;
            }
            finally
            {
                if (!success)
                    proxy.Abort();
            }
        }

        static ChannelFactory<TServiceContract> GetChannelByContract(string contractName)
        {
            return new ChannelFactory<TServiceContract>(contractName);
        }
    }
}
